package com.dnjn.happiness.emo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnjn.happiness.common.core.constant.Constants;
import com.dnjn.happiness.common.core.constant.HappyConstants;
import com.dnjn.happiness.common.core.utils.DateUtils;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.core.utils.bean.BeanUtils;
import com.dnjn.happiness.emo.api.domain.EmoAvgScoreWeekly;
import com.dnjn.happiness.emo.api.domain.WeeklyRankingBean;
import com.dnjn.happiness.emo.domain.EmoHscoreLog;
import com.dnjn.happiness.emo.api.domain.UserModelScore;
import com.dnjn.happiness.emo.mapper.EmoHscoreLogMapper;
import com.dnjn.happiness.emo.service.IEmoAvgScoreWeeklyService;
import com.dnjn.happiness.emo.service.IEmoHscoreLogService;
import com.dnjn.happiness.emo.service.IUserModelScoreService;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 快乐分波动记录Service业务层处理
 *
 * @author happiness
 * @date 2024-03-28
 */
@Service
public class EmoHscoreLogServiceImpl extends ServiceImpl<EmoHscoreLogMapper, EmoHscoreLog> implements IEmoHscoreLogService {
    private static final Logger log = LoggerFactory.getLogger(EmoHscoreLogServiceImpl.class);
    @Autowired
    private IEmoAvgScoreWeeklyService emoAvgScoreWeeklyService;

    @Autowired
    private IUserModelScoreService userModelScoreService;

    @Autowired
    private IEmoHscoreLogService emoHscoreLogService;


    @Override
    public List<EmoHscoreLog> queryEexportLog() {
        return baseMapper.queryEexportLog();
    }

    @Override
    public Double queryCurrentWeek(Long userId, String rType) {

        return baseMapper.queryCurrentWeek(userId, rType);
    }

    @Override
    public void getExport(HttpServletResponse response, Long deptId) {
        //查询当前周
        int week = DateUtils.getWeek();
        //当前年数
        int year = DateUtils.getYear();
        String weekOfYear = String.format("%04d%02d", year, week);
        SXSSFWorkbook workbook = new SXSSFWorkbook(500);
        CellStyle style = createCellStyle(workbook);
        exportExcelLog(workbook, style, week, year, weekOfYear,deptId);
        try {
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            log.error("导出Excel异常{}", e.getMessage());
        } finally {
            IOUtils.closeQuietly(workbook);
        }


    }

    private CellStyle createCellStyle(SXSSFWorkbook workbook) {
        CellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        return style;
    }

    private void exportExcelLog(SXSSFWorkbook workbook, CellStyle style, int week, int year, String weekOfYear, Long deptId) {

        List<WeeklyRankingBean> agoList = emoAvgScoreWeeklyService.getTopTen(weekOfYear, deptId);
        List<WeeklyRankingBean> afterList = emoAvgScoreWeeklyService.getLastTen(weekOfYear, deptId);
        List<EmoAvgScoreWeekly> waveList = emoAvgScoreWeeklyService.getLargeFluctuate(weekOfYear, deptId);

        agoList.stream().forEach(item -> {
            Long userId = item.getUserId();
            List<UserModelScore> list = userModelScoreService.lambdaQuery().eq(UserModelScore::getUserId, userId).eq(UserModelScore::getDeleted, Constants.UNDELETED).list();//五条
            for (UserModelScore userModelScore : list) {

                EmoHscoreLog emoHscoreLog = getRemarkInfo(userId, userModelScore.getRtype());
                queryEmoHscoreLog(emoHscoreLog, item);//更新item数据
            }
        });

        afterList.stream().forEach(item -> {
            Long userId = item.getUserId();
            List<UserModelScore> list = userModelScoreService.lambdaQuery().eq(UserModelScore::getUserId, userId).eq(UserModelScore::getDeleted, Constants.UNDELETED).list();//五条
            for (UserModelScore userModelScore : list) {

                EmoHscoreLog emoHscoreLog = getRemarkInfo(userId, userModelScore.getRtype());
                queryEmoHscoreLog(emoHscoreLog, item);//更新item数据
            }
        });

        waveList.stream().forEach(item -> {
            Long userId = item.getUserId();
            List<UserModelScore> list = userModelScoreService.lambdaQuery().eq(UserModelScore::getUserId, userId).eq(UserModelScore::getDeleted, Constants.UNDELETED).list();//五条
            for (UserModelScore userModelScore : list) {

                EmoHscoreLog emoHscoreLog = getRemarkInfo(userId, userModelScore.getRtype());
                queryEmoHscoreLogWav(emoHscoreLog, item);//更新item数据
            }
        });

        SXSSFSheet sheet = workbook.createSheet("第" + week + "周");
        createTitle(style, sheet, year + "年第" + week + "周", 0, 0, 0, 0, 0, 37);

        mergeCell(sheet, 1, 1, 0, 11);
        mergeCell(sheet, 1, 1, 12, 24);
        mergeCell(sheet, 1, 1, 25, 36);
        SXSSFRow rowOne = sheet.createRow(1);
        setCellValueByRow(style, rowOne, 0, "前10名");
        setCellValueByRow(style, rowOne, 12, "后10名");
        setCellValueByRow(style, rowOne, 25, "波动较大10名");
        SXSSFRow secondRow = sheet.createRow(2);
        createSecondRow(style, sheet, secondRow);
        cellDataFilling(agoList, afterList, waveList, sheet);

    }


    private void cellDataFilling(List<WeeklyRankingBean> agoList, List<WeeklyRankingBean> afterList, List<EmoAvgScoreWeekly> waveList, SXSSFSheet sheet) {
        int index = 0;
        for (int i = 3; i <= 12; i++) {
            SXSSFRow row = sheet.createRow(i);
            index = 0;
            for (int j = 0; j <= 2; j++) {
                SXSSFCell cell0 = row.createCell(index);
                index++;
                SXSSFCell cell1 = row.createCell(index);
                index++;
                SXSSFCell cell2 = row.createCell(index);
                index++;
                SXSSFCell cell3 = row.createCell(index);
                index++;
                SXSSFCell cell4 = row.createCell(index);
                index++;
                SXSSFCell cell5 = row.createCell(index);
                index++;
                SXSSFCell cell6 = row.createCell(index);
                index++;
                SXSSFCell cell7 = row.createCell(index);
                index++;
                SXSSFCell cell8 = row.createCell(index);
                index++;
                SXSSFCell cell9 = row.createCell(index);
                index++;
                SXSSFCell cell10 = row.createCell(index);
                index++;
                WeeklyRankingBean weekly = null;
                EmoAvgScoreWeekly emoAvgScoreWeekly;
                if (j == 0) {
                    weekly = CollectionUtils.isEmpty(agoList) ? new WeeklyRankingBean() : agoList.get(i - 3);
                } else if (j == 1) {
                    weekly = CollectionUtils.isEmpty(afterList) ? new WeeklyRankingBean() : afterList.get(i - 3);
                } else {
                    emoAvgScoreWeekly = CollectionUtils.isEmpty(waveList) ? new EmoAvgScoreWeekly() : waveList.get(i - 3);
                    weekly = new WeeklyRankingBean();
                    BeanUtils.copyPropsIgnoreNull(emoAvgScoreWeekly,weekly);
                }
                cell0.setCellValue((i - 2) + "");
                cell1.setCellValue(weekly.getEmpno());
                cell2.setCellValue(weekly.getNickName());
                cell3.setCellValue(StringUtils.isNotNull(weekly.getScoreAvg()) ? weekly.getScoreAvg().toString() : "");
                cell4.setCellValue(StringUtils.isNotNull(weekly.getAi()) ? weekly.getAi() : "");
                cell5.setCellValue(StringUtils.isNotNull(weekly.getAppraise()) ? weekly.getAppraise() : "");
                cell6.setCellValue(StringUtils.isNotNull(weekly.getSurvey()) ? weekly.getSurvey() : "");
                cell7.setCellValue(StringUtils.isNotNull(weekly.getAdvice()) ? weekly.getAdvice() : "");
                cell8.setCellValue(StringUtils.isNotNull(weekly.getTraining()) ? weekly.getTraining() : "");
                cell9.setCellValue(StringUtils.isNotNull(weekly.getCommunicate()) ? weekly.getCommunicate() : "");
                cell10.setCellValue(StringUtils.isNotNull(weekly.getAttendance()) ? weekly.getAttendance() : "");

            }
        }
    }


    private void createSecondRow(CellStyle style, SXSSFSheet sheet, SXSSFRow secondRow) {
        List<String> list = new ArrayList<>();
        list.add("名次");
        list.add("工号");
        list.add("姓名");
        list.add("平均快乐值");
        list.add("Ai打卡");
        list.add("评价");
        list.add("问卷");
        list.add("建议");
        list.add("培训");
        list.add("沟通");
        list.add("考勤");
        int flag = 0;
        for (int i = 0; i <= 2; i++) {
            for (int j = 0; j <= 10; j++) {
                SXSSFCell cell = secondRow.createCell(flag);
                cell.setCellStyle(style);
                cell.setCellValue(list.get(j));
                flag++;
                sheet.setColumnWidth(flag, 3000);
            }
        }
    }

    private void setCellValueByRow(CellStyle style, SXSSFRow rowOne, int cellIndex, String cellValue) {
        SXSSFCell cell0 = rowOne.createCell(cellIndex);
        cell0.setCellValue(cellValue);
        cell0.setCellStyle(style);
    }

    private void mergeCell(SXSSFSheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        CellRangeAddress cellAddresses = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        sheet.addMergedRegion(cellAddresses);
    }

    private void createTitle(CellStyle style, SXSSFSheet sheet, String cellValue, int startRowIndex, int startCellIndex, int firstRow, int lastRow, int firstCol, int lastCol) {
        SXSSFRow titleRow = sheet.createRow(startRowIndex);
        SXSSFCell headCell = titleRow.createCell(startCellIndex);
        headCell.setCellValue(cellValue);
        headCell.setCellStyle(style);
        CellRangeAddress cellAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        sheet.addMergedRegion(cellAddress);
    }

    private void queryEmoHscoreLog(EmoHscoreLog emoHscoreLog, WeeklyRankingBean weeklyRankingBean) {
        if (!StringUtils.isEmpty(emoHscoreLog.getAdvice())) {
            weeklyRankingBean.setAdvice(emoHscoreLog.getAdvice());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAppraise())) {
            weeklyRankingBean.setAppraise(emoHscoreLog.getAppraise());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getSurvey())) {
            weeklyRankingBean.setSurvey(emoHscoreLog.getSurvey());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAttendance())) {
            weeklyRankingBean.setAttendance(emoHscoreLog.getAttendance());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAi())) {
            weeklyRankingBean.setAi(emoHscoreLog.getAi());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getTraining())) {
            weeklyRankingBean.setTraining(emoHscoreLog.getTraining());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getCommunicate())) {
            weeklyRankingBean.setCommunicate(emoHscoreLog.getCommunicate());
        }

    }

    private void queryEmoHscoreLogWav(EmoHscoreLog emoHscoreLog, EmoAvgScoreWeekly weeklyRankingBean) {
        if (!StringUtils.isEmpty(emoHscoreLog.getAdvice())) {
            weeklyRankingBean.setAdvice(emoHscoreLog.getAdvice());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAppraise())) {
            weeklyRankingBean.setAppraise(emoHscoreLog.getAppraise());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getSurvey())) {
            weeklyRankingBean.setSurvey(emoHscoreLog.getSurvey());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAttendance())) {
            weeklyRankingBean.setAttendance(emoHscoreLog.getAttendance());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getAi())) {
            weeklyRankingBean.setAi(emoHscoreLog.getAi());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getTraining())) {
            weeklyRankingBean.setTraining(emoHscoreLog.getTraining());
        }
        if (!StringUtils.isEmpty(emoHscoreLog.getCommunicate())) {
            weeklyRankingBean.setCommunicate(emoHscoreLog.getCommunicate());
        }

    }

    private EmoHscoreLog getRemarkInfo(Long userId, String rtype) {
        EmoHscoreLog emoHscoreLog = new EmoHscoreLog();
        if (rtype.equals("APPRAISE")) {
            String appraise = getRemark(userId, HappyConstants.EMO_USER_RTYPE_APPRAISE);
            emoHscoreLog.setAppraise(appraise);
        }
        if (rtype.equals("SURVEY")) {
            String survey = getRemark(userId, HappyConstants.EMO_USER_RTYPE_SURVEY);
            emoHscoreLog.setSurvey(survey);
        }
        if (rtype.equals("TRAINING")) {
            String training = getRemark(userId, HappyConstants.EMO_USER_RTYPE_TRAINING);
            emoHscoreLog.setTraining(training);
        }
        if (rtype.equals("ADVICE")) {
            String advice = getRemark(userId, HappyConstants.EMO_USER_RTYPE_ADVICE);
            emoHscoreLog.setAdvice(advice);
        }
        if (rtype.equals("AI")) {
            String ai = getRemark(userId, HappyConstants.EMO_USER_RTYPE_AI);
            emoHscoreLog.setAi(ai);
        }
        if (rtype.equals("COMM")) {
            String comm = getRemark(userId, HappyConstants.EMO_USER_RTYPE_COMM);
            emoHscoreLog.setCommunicate(comm);
        }
        if (rtype.equals("ATTENDANCE")) {
            String hcm = getRemark(userId, HappyConstants.EMO_USER_RTYPE_ATTENDANCE);
            emoHscoreLog.setAttendance(hcm);
        }
        return emoHscoreLog;
    }

    private String getRemark(Long userId, String rtype) {
        String remark = "";
        UserModelScore userModelScore = userModelScoreService.lambdaQuery().eq(UserModelScore::getUserId, userId).eq(UserModelScore::getDeleted, Constants.UNDELETED).eq(UserModelScore::getRtype, rtype).one();
        String modelTotalScore = userModelScore.getTotalScore().toString();
        Double score = emoHscoreLogService.queryCurrentWeek(userId, rtype);

        if (null != score) {
            String scoreChange = score.toString();
//            remark.concat(modelTotalScore);
//            remark.concat("(波动");
//            remark.concat(scoreChange);
//            remark.concat(")");
            remark = modelTotalScore + "(波动" + scoreChange + ")";
            return remark;
        }
        return modelTotalScore;

    }
}
